﻿using System;
using System.Drawing;
using System.Management;
using System.Runtime.InteropServices;
using CSW.Framework.Windows.Win32API;

namespace CSW.Framework.Windows
{
    /// <summary>
    /// Exposes file system properties.
    /// </summary>
    public static class FileSystem
    {
        /// <summary>
        /// Gets the logical drives as a <see cref="ManagementObjectCollection"/>.
        /// </summary>
        /// <returns>The logical drives as a <see cref="ManagementObjectCollection"/>.</returns>
        public static ManagementObjectCollection GetDrivesAsManagementObjectCollection()
        {
            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_LogicalDisk");
            ManagementObjectCollection queryCollection = query.Get();
            return queryCollection;
        }

        /// <summary>
        /// Gets the logical drives.
        /// </summary>
        public static void GetDrives()
        {
            // TODO - finish implementing
            ManagementObjectCollection queryCollection = GetDrivesAsManagementObjectCollection();
            foreach (ManagementObject drive in queryCollection)
            {
                foreach (PropertyData prop in drive.Properties)
                {
                    Console.WriteLine(string.Format("{0} {1}", prop.Name, prop.Value));
                }
                Console.WriteLine("================");
            }
        }

        /// <summary>Icon Size.</summary>
        public enum IconSize
        {
            /// <summary>Small icon size. </summary>
            Small,
            /// <summary>Large icon size.</summary>
            Large
        }

        /// <summary>
        /// Gets the file icon.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="iconSize">Size of the icon.</param>
        /// <returns>The file icon.</returns>
        public static Icon GetFileIcon(string path, IconSize iconSize)
        {
            const UInt32 dwAttribs = Win32.SHGFI_USEFILEATTRIBUTES | Win32.FILE_ATTRIBUTE_NORMAL;
            return GetPathIcon(path, iconSize, dwAttribs);
        }

        /// <summary>
        /// Gets the file icon.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="iconSize">Size of the icon.</param>
        /// <returns>The file icon.</returns>
        public static Icon GetDirectoryIcon(string path, IconSize iconSize)
        {
            const UInt32 dwAttribs = Win32.SHGFI_USEFILEATTRIBUTES | Win32.FILE_ATTRIBUTE_DIRECTORY;
            return GetPathIcon(path, iconSize, dwAttribs);
        }

        private static Icon GetPathIcon(string path, IconSize iconSize, UInt32 dwAttribs)
        {
            try
            {
                UInt32 uFlags = Win32.SHGFI_ICON;
                if (iconSize == IconSize.Small)
                    uFlags = uFlags | Win32.SHGFI_SMALLICON;
                else
                    uFlags = uFlags | Win32.SHGFI_LARGEICON;

                Win32.SHFILEINFO shInfo = new Win32.SHFILEINFO();
                Win32.SHGetFileInfo(path, dwAttribs, ref shInfo, Convert.ToUInt32(Marshal.SizeOf(shInfo)), uFlags);

                Icon fileIcon = Icon.FromHandle(shInfo.hIcon).Clone() as Icon;
                Win32.DestroyIcon(shInfo.hIcon);
                return fileIcon;
            }
            catch
            {
                return null;
            }
        }

    }
}
